home *** CD-ROM | disk | FTP | other *** search
- /* exncode.c
- *
- * COPYRIGHT (c) 1990 by AT&T Bell Laboratories.
- *
- * NOTE: this file should be merged with signal.c
- */
-
- #ifdef MIPS
- #ifdef sony_news
- #include <machine/cpu.h> /* for EXC_OV */
- #else
- #ifndef SGI
- #include <mips/cpu.h> /* for EXC_OV */
- #else
- #include <sys/sbd.h> /* for EXC_OV */
- #endif
- #endif
- #endif
- #include <signal.h>
- #ifdef DYNIX
- #include <sys/types.h>
- #include <machine/fpu.h>
- #endif
- #include "tags.h"
- #include "ml_types.h"
-
- extern int div_e0[], overflow_e0[];
-
- #ifdef HPUX
- # define CODE_FLTDIV 0x0400
- # ifdef HPPA
- # define CODE_FLTOVF 12
- # else
- # define CODE_FLTOVF 0x1000
- # define CODE_FLTUND 0x0800
- # ifndef FPE_FLTOPERR_TRAP
- # define FPE_FLTOPERR_TRAP 0x2000
- # endif
- # endif
- #endif
-
- #ifdef NeXT
- /* these are taken from the 0.9 include files */
- # define CODE_OVERFLOW 0x1c
- # define CODE_ZERODIV 0x14
- # define CODE_FLTDIV 0xc8
- # define CODE_FLTOVF 0xd4
- # define CODE_FLTUND 0xcc
- #endif
-
- #ifdef THINK_C
- #include "MacOS.dep.h"
- # define CODE_OVERFLOW 0x1c
- # define CODE_ZERODIV 0x14
- /* these are taken from the NEXT defn above -- e, check this! */
- # define CODE_FLTDIV 0xc8
- # define CODE_FLTOVF 0xd4
- # define CODE_FLTUND 0xcc
- #endif
-
- /* make_exn_code:
- * Map a UNIX (signal, code) pair to an ML (exception, arg) pair.
- */
- #if defined(AIX)
- #include <fpxcp.h>
-
- void make_exn_code(msp,scp,sig,code)
- MLState_ptr msp;
- struct sigcontext *scp;
- int sig, code;
- {
- switch (sig)
- {
- case SIGTRAP:
- {
- fp_ctx_t flt_context;
-
- fp_sh_trap_info(scp,&flt_context);
- if (flt_context.trap & FP_DIV_BY_ZERO)
- {
- msp->fault_exn = PTR_CtoML(div_e0+1);
- return;
- }
- else {
- msp->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- }
- }
- default:
- die("Unknown signal %d\n", sig);
- }
- }
- #else
- void make_exn_code (MLState,scp,sig,code)
- MLState_ptr MLState;
- struct sigcontext *scp;
- int sig, code;
- {
- switch (sig) {
- #ifdef THINK_C
- case SIGTRAP:
- #else
- case SIGFPE:
- #endif
- #if defined(HPUX) && !defined(HPPA)
- if (code == 5) {
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- return;
- }
- else
- code &= 0x3c00; /* grab exception status */
- #endif /* HPUX && !HPPA */
-
- #ifdef HPPA
- /* The cause of the floating exception could be
- ** dumped into any of the floating exception registers
- */
- {
- struct save_state *ss;
-
- ss = &(scp->sc_sl.sl_ss);
- if ((ss->ss_frexcp1 & 0x40000000) ||
- (ss->ss_frexcp2 & 0x40000000) ||
- (ss->ss_frexcp3 & 0x40000000) ||
- (ss->ss_frexcp4 & 0x40000000) ||
- (ss->ss_frexcp5 & 0x40000000) ||
- (ss->ss_frexcp6 & 0x40000000) ||
- (ss->ss_frexcp7 & 0x40000000))
- {
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- return;
- }
- else if ((ss->ss_frexcp1 & 0x20000000) ||
- (ss->ss_frexcp2 & 0x20000000) ||
- (ss->ss_frexcp3 & 0x20000000) ||
- (ss->ss_frexcp4 & 0x20000000) ||
- (ss->ss_frexcp5 & 0x20000000) ||
- (ss->ss_frexcp6 & 0x20000000) ||
- (ss->ss_frexcp7 & 0x20000000))
-
- {
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- }
- }
- #endif /* HPPA */
-
- #ifdef AUX
- if (code == 5) { /* integer divide by zero */
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- }
- else
- die("unexpected floating point error: %d\n", code);
- return;
- #else
-
- /* MACH maps mips exceptions to the corresponding BSD exceptions; it
- does it right */
-
- #if defined(MIPS) && !defined(MACH)
- if (code == EXC_OV) {
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- }
- else {
- /* code contains the FP control/status register */
- if (code & 0x4000) /* bit-14 is overflow */
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- else if (code & 0x18000) /* bit-15 is divide by zero,
- bit-16 is 0/0 */
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- else if (code & 0x2000 /* bit-13 is underflow */)
- die("underflow should not trap\n");
- #ifdef SGI
- else if (code == 14) /* no known symbolic constant for this */
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- #endif
- else
- die("strange floating point error, %d\n",code);
- }
- return;
- #else
- switch (code) {
- #ifdef CODE_OVERFLOW
- case CODE_OVERFLOW:
- #endif
- #ifdef FPE_TRAPV_TRAP
- case FPE_TRAPV_TRAP:
- #endif
- #ifdef FPE_INTOVF_TRAP
- case FPE_INTOVF_TRAP:
- #endif
- #ifdef FPE_FLTOVF_TRAP
- case FPE_FLTOVF_TRAP:
- #endif
- #ifdef FPE_FLTOVF_FAULT
- case FPE_FLTOVF_FAULT:
- #endif
- #ifdef K_INTOVF
- case K_INTOVF:
- #endif
- #ifdef CODE_FLTOVF
- case CODE_FLTOVF:
- #endif
- #ifdef K_FLTOVF
- case K_FLTOVF:
- #endif
- #if defined(SPARC) && defined (MACH)
- case 0x8:
- #endif
- #if defined(HPPA)
- case 14:
- #endif
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- #ifdef CODE_ZERODIV
- case CODE_ZERODIV:
- #endif
- #ifdef FPE_INTDIV_TRAP
- case FPE_INTDIV_TRAP:
- #endif
- #ifdef FPE_FLTDIV_TRAP
- case FPE_FLTDIV_TRAP:
- #endif
- #ifdef FPE_FLTDIV_FAULT
- case FPE_FLTDIV_FAULT:
- #endif
- #ifdef FPE_FLTOPERR_TRAP /* sun-3&4s generate this on 0.0/0.0 */
- case FPE_FLTOPERR_TRAP:
- #endif
- #ifdef FPE_FLTINV_TRAP /* I387's generate this on 0.0/0.0 */
- case FPE_FLTINV_TRAP:
- #endif
- #ifdef CODE_FLTDIV
- case CODE_FLTDIV:
- #endif
- #ifdef K_INTDIV
- case K_INTDIV:
- #endif
- #ifdef K_FLTDIV
- case K_FLTDIV:
- #endif
- #if defined(SPARC) && defined(MACH)
- case 0x82:
- #endif
- #if defined(HPPA) && defined(HPUX)
- case 13: /* what's the proper symbolic name for this? XXX */
-
- #endif
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- return;
- #ifdef CODE_FLTUND
- case CODE_FLTUND:
- #endif
- #ifdef K_FLTUND
- case K_FLTUND:
- #endif
- #ifdef FPE_FLTUND_TRAP
- case FPE_FLTUND_TRAP:
- #endif
- #ifdef FPE_FLTUND_FAULT
- case FPE_FLTUND_FAULT:
- #endif
- die("underflow should not trap\n");
- default:
- die("strange floating point error, %#x\n", code);
- }
- #endif MIPS
- #endif AUX
-
- #ifndef THINK_C
- case SIGEMT:
- die("Floating point EMT trap (68881 not installed?)\n");
- #endif
-
- #ifdef HPUX
- case SIGILL:
- if (code == 7) {
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- }
- else
- die ("exnCode: code was %d\n",code);
- #endif HPUX
-
- #ifdef AUX
- case SIGILL:
- if (code == 7) { /* integer overflow trap */
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- }
- else
- die ("unexpected illegal instruction trap: %d\n",code);
- return;
- #endif AUX
-
- #if defined(SPARC) && defined(MACH)
- case SIGILL:
- if (code == 0x87) {
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- } else
- die ("SIGILL code 0x%x\n",code);
- #endif /* defined(SPARC) && defined(MACH) */
- #ifdef MIPS
- case SIGTRAP:
- switch (code) {
- case BRK_OVERFLOW:
- MLState->fault_exn = PTR_CtoML(overflow_e0+1);
- return;
- case BRK_DIVZERO:
- MLState->fault_exn = PTR_CtoML(div_e0+1);
- return;
- default:
- die("illegal BREAK instruction");
- }
- #endif MIPS
- } /* end of switch */
-
- } /* end of make_exn_code */
- #endif AIX
-